package com.yb.xczx.cloud.auth.controller;

import com.alibaba.fastjson2.JSONObject;
import com.yb.xczx.cloud.auth.bean.XczxUserPassAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright (C), 2022-2023, 姚兵
 * Author: 32210
 * Date: 2023/5/17 11:09
 * FileName: Oauth2AuthEndpointController
 * Description:
 */

@Controller
@Slf4j
public class Oauth2AuthEndpointController {

    @Autowired
    RegisteredClientRepository registeredClientRepository;

    @Autowired
    OAuth2AuthorizationConsentService oAuth2AuthorizationConsentService;

    @RequestMapping("/oauth2/consent/cat")
    @ResponseBody
    public String consent(String clientId,String name){
        RegisteredClient registeredClient = registeredClientRepository.findByClientId(clientId);
        OAuth2AuthorizationConsent consent = oAuth2AuthorizationConsentService.findById(registeredClient.getId(), name);
        return JSONObject.toJSONString(consent);
    }

    @RequestMapping("/oauth2/code/url")
    public String oauthCodeUrl(Model mav,@RequestAttribute String authCodeUrl){
        mav.addAttribute("authCodeUrl",authCodeUrl);
        return "oauth-code";
    }
    @RequestMapping("/oauth2/consent/clear")
    @ResponseBody
    public String consentClear(String clientId,String name){
        RegisteredClient registeredClient = registeredClientRepository.findByClientId(clientId);
        if(Objects.isNull(registeredClient)){
            return "error";
        }
        OAuth2AuthorizationConsent consent = oAuth2AuthorizationConsentService.findById(registeredClient.getId(), name);

        if(Objects.isNull(consent)){
            return "error";
        }
            oAuth2AuthorizationConsentService.remove(consent);

        return "success";
    }
    @RequestMapping("/oauth2/consent/custom")
    public ModelAndView consent(HttpServletRequest request, HttpServletResponse response, @RequestParam("scope") String scopeStr,
                        @RequestParam String client_id,
                        @RequestParam String access_token,
                        @RequestParam String state,Authentication authentication) throws IOException {

        RegisteredClient registeredClient = registeredClientRepository.findByClientId(client_id);

        //封装 请求的scope
        String referer = request.getHeader("Referer");
        log.info("Oauth2AuthEndpointController Referer:{}",referer);
        HashSet<String> requestedScopes = new HashSet<>(Arrays.asList(scopeStr.split(" ")));
        ModelAndView mav = new ModelAndView();
        mav.addObject("clientId",client_id);
        mav.addObject("requestedScopes",requestedScopes);

        mav.addObject("access_token",access_token);

        //查询已经授权的scope
        User principal = (User) authentication.getPrincipal();
        OAuth2AuthorizationConsent consent = oAuth2AuthorizationConsentService.findById(registeredClient.getId(), principal.getUsername());

        Set<String> authorizedScopes = consent==null?Collections.emptySet():consent.getScopes();


        mav.addObject("authorizedScopes", authorizedScopes);

        //封装页面数据
        Set<String> scopesToAuthorize = new HashSet<>();
        Set<String> scopesPreviouslyAuthorized = new HashSet<>();
        for (String scope : requestedScopes) {
            if (authorizedScopes.contains(scope)) {
                scopesPreviouslyAuthorized.add(scope);
            } else if (!scope.equals(OidcScopes.OPENID)) { // openid scope does not require consent
                scopesToAuthorize.add(scope);
            }
        }
        mav.addObject("scopesToAuthorize", scopesToAuthorize);
        mav.addObject("scopesPreviouslyAuthorized", scopesPreviouslyAuthorized);
        mav.addObject("state", state);
        mav.setViewName("oauth-consent");
        return mav;
    }



    @ResponseBody
    @GetMapping("/oauth2/userinfo")
    public Object oauth2Userinfo(Authentication authentication){
        XczxUserPassAuthenticationToken token= (XczxUserPassAuthenticationToken) authentication;

        log.info("oauth2Userinfo ");
        return token.getXczxSysUser();
    }


}
